﻿namespace Compass.Maui.Services;
//1、定义事件参数，知道谁发生了变化。
public class UserLoggedEventArgs : EventArgs
{
    public UserLoggedEventArgs(UserDto user)
    {
        LoggedUser=user;
    }
    //指明谁登录了
    public UserDto LoggedUser { get; set; }
}

public interface ILoginService
{
    Task<bool> LoginAsync(UserDto user);
    Task LogoutAsync();
    //2、自定义事件。
    event EventHandler<UserLoggedEventArgs> Logged;
}
public class LoginService:ILoginService
{
    private const string ServiceName = "Login";
    private readonly IHttpRestClient _client;
    private readonly IPreferenceService _preferenceService;

    //键值存储
    //Preferences.Get(key, defaultValue);
    //Preferences.Set(key, value);
    
    public LoginService(IHttpRestClient client, IPreferenceService preferenceService)
    {
        _client = client;
        _preferenceService = preferenceService;
    }


    public async Task<bool> LoginAsync(UserDto user)
    {
        BaseRequest request = new()
        {
            Method=RestSharp.Method.Post,
            Route=$"{ServiceName}/Name",
            Param=user
        };

        var loginResult = await _client.ExecuteAsync<string>(request);
        if (!loginResult.Status) return loginResult.Status;

        //获取token，并从token中解析出用户名、id和角色
        var token = loginResult.Result;

        ClaimsIdentity identity = new(ParseClaimsFromJwt(token), "jwt");
        var id = identity.Claims.First(x => x.Type == ClaimTypes.NameIdentifier).Value;
            
        var role = identity.Claims.First(x => x.Type == ClaimTypes.Role).Value;
            
        var dto = new UserDto { Id = Guid.Parse(id), UserName = identity.Name, Role = role };

        //键值存储
        _preferenceService.Set(Consts.Token, token);
        _preferenceService.Set(Consts.UserId, id);
        _preferenceService.Set(Consts.Role, role);
        _preferenceService.Set(Consts.UserName,user.UserName);
        _preferenceService.Set(Consts.Password,user.Password);

        //3、触发登录事件(登录以后)。
        Logged?.Invoke(this,new UserLoggedEventArgs(dto));
        return loginResult.Status;
    }

    public Task LogoutAsync()
    {
        //清空Token键值存储
        _preferenceService.Set(Consts.Token, "");

        return Task.CompletedTask;
    }

    public event EventHandler<UserLoggedEventArgs>? Logged;

    #region 解析Token内容的代码
    public static IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
    {
        var payload = jwt.Split('.')[1];
        var jsonBytes = ParseBase64WithoutPadding(payload);
        var keyValuePairs = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(jsonBytes);
        return keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString()));
    }
    private static byte[] ParseBase64WithoutPadding(string base64)
    {
        switch (base64.Length % 4)
        {
            case 2: base64 += "=="; break;
            case 3: base64 += "="; break;
        }
        return Convert.FromBase64String(base64);
    }
    #endregion
}